import platform
import psutil
import os
import socket
from datetime import datetime
from typing import Dict, Any
import logging

logger = logging.getLogger(__name__)

class SystemInfoService:
    """系统信息获取服务"""
    
    def __init__(self):
        pass
    
    def get_system_info(self) -> Dict[str, Any]:
        """获取系统基本信息"""
        try:
            return {
                "system": platform.system(),
                "system_version": platform.version(),
                "machine": platform.machine(),
                "processor": platform.processor(),
                "architecture": platform.architecture()[0],
                "hostname": socket.gethostname(),
                "boot_time": datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S"),
                "python_version": platform.python_version(),
                "platform": platform.platform()
            }
        except Exception as e:
            logger.error(f"获取系统信息失败: {str(e)}")
            return {}
    
    def get_cpu_info(self) -> Dict[str, Any]:
        """获取CPU信息"""
        try:
            cpu_count = psutil.cpu_count()
            cpu_freq = psutil.cpu_freq()
            cpu_percent = psutil.cpu_percent(interval=1)
            
            return {
                "cpu_count": cpu_count,
                "cpu_count_logical": psutil.cpu_count(logical=True),
                "cpu_freq_current": round(cpu_freq.current, 2) if cpu_freq else 0,
                "cpu_freq_max": round(cpu_freq.max, 2) if cpu_freq else 0,
                "cpu_percent": round(cpu_percent, 2),
                "cpu_per_core": [round(x, 2) for x in psutil.cpu_percent(interval=1, percpu=True)]
            }
        except Exception as e:
            logger.error(f"获取CPU信息失败: {str(e)}")
            return {}
    
    def get_memory_info(self) -> Dict[str, Any]:
        """获取内存信息"""
        try:
            memory = psutil.virtual_memory()
            swap = psutil.swap_memory()
            
            return {
                "memory_total": round(memory.total / (1024**3), 2),  # GB
                "memory_available": round(memory.available / (1024**3), 2),  # GB
                "memory_used": round(memory.used / (1024**3), 2),  # GB
                "memory_percent": round(memory.percent, 2),
                "swap_total": round(swap.total / (1024**3), 2),  # GB
                "swap_used": round(swap.used / (1024**3), 2),  # GB
                "swap_percent": round(swap.percent, 2)
            }
        except Exception as e:
            logger.error(f"获取内存信息失败: {str(e)}")
            return {}
    
    def get_disk_info(self) -> Dict[str, Any]:
        """获取磁盘信息"""
        try:
            disk_usage = psutil.disk_usage('/')
            disk_io = psutil.disk_io_counters()
            
            partitions = []
            for partition in psutil.disk_partitions():
                try:
                    partition_usage = psutil.disk_usage(partition.mountpoint)
                    partitions.append({
                        "device": partition.device,
                        "mountpoint": partition.mountpoint,
                        "fstype": partition.fstype,
                        "total": round(partition_usage.total / (1024**3), 2),  # GB
                        "used": round(partition_usage.used / (1024**3), 2),  # GB
                        "free": round(partition_usage.free / (1024**3), 2),  # GB
                        "percent": round((partition_usage.used / partition_usage.total) * 100, 2)
                    })
                except PermissionError:
                    continue
            
            return {
                "disk_total": round(disk_usage.total / (1024**3), 2),  # GB
                "disk_used": round(disk_usage.used / (1024**3), 2),  # GB
                "disk_free": round(disk_usage.free / (1024**3), 2),  # GB
                "disk_percent": round((disk_usage.used / disk_usage.total) * 100, 2),
                "partitions": partitions,
                "disk_read_bytes": disk_io.read_bytes if disk_io else 0,
                "disk_write_bytes": disk_io.write_bytes if disk_io else 0
            }
        except Exception as e:
            logger.error(f"获取磁盘信息失败: {str(e)}")
            return {}
    
    def get_network_info(self) -> Dict[str, Any]:
        """获取网络信息"""
        try:
            network_io = psutil.net_io_counters()
            network_connections = len(psutil.net_connections())
            
            # 获取网络接口信息
            interfaces = []
            for interface, addrs in psutil.net_if_addrs().items():
                for addr in addrs:
                    if addr.family == socket.AF_INET:  # IPv4
                        interfaces.append({
                            "interface": interface,
                            "ip": addr.address,
                            "netmask": addr.netmask,
                            "broadcast": addr.broadcast
                        })
            
            return {
                "bytes_sent": network_io.bytes_sent,
                "bytes_recv": network_io.bytes_recv,
                "packets_sent": network_io.packets_sent,
                "packets_recv": network_io.packets_recv,
                "connections": network_connections,
                "interfaces": interfaces
            }
        except Exception as e:
            logger.error(f"获取网络信息失败: {str(e)}")
            return {}
    
    def get_process_info(self) -> Dict[str, Any]:
        """获取进程信息"""
        try:
            processes = []
            for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
                try:
                    processes.append(proc.info)
                except (psutil.NoSuchProcess, psutil.AccessDenied):
                    continue
            
            # 按CPU使用率排序，取前10个
            processes.sort(key=lambda x: x['cpu_percent'], reverse=True)
            
            return {
                "total_processes": len(psutil.pids()),
                "top_processes": processes[:10]
            }
        except Exception as e:
            logger.error(f"获取进程信息失败: {str(e)}")
            return {}
    
    def get_all_info(self) -> Dict[str, Any]:
        """获取所有系统信息"""
        return {
            "system": self.get_system_info(),
            "cpu": self.get_cpu_info(),
            "memory": self.get_memory_info(),
            "disk": self.get_disk_info(),
            "network": self.get_network_info(),
            "process": self.get_process_info(),
            "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        }
